import socket
import threading

# 异或加密/解密函数
def xor_crypt(data, key):
    return bytes([b ^ key for b in data])

def handle_client(client_socket, addr):
    print(f"[*] 接受来自 {addr[0]}:{addr[1]} 的连接")
    try:
        while True:  # 添加循环保持连接
            # 接收客户端选择的功能
            choice = client_socket.recv(1024).decode()
            if choice == "0":
                print(f"[*] 客户端 {addr} 请求断开连接")
                break
            if choice == "1":
                # 基本通信功能
                while True:
                    message = client_socket.recv(1024).decode()
                    if message == "exit":
                        break
                    print(f"[{addr}] 收到消息: {message}")
                    reply = input("请输入回复：")
                    client_socket.send(reply.encode())

            elif choice == "2":
                # 加密传输功能
                try:
                    # 接收密钥
                    key = int(client_socket.recv(1024).decode())
                    print(f"[*] 使用异或密钥: {key}")
                    # 接收文件名
                    filename = client_socket.recv(1024).decode()
                    print(f"[*] 接收文件: {filename}")
                    # 接收加密数据
                    encrypted_data = b""
                    while True:
                        chunk = client_socket.recv(4096)
                        if not chunk:
                            break
                        encrypted_data += chunk
                    print(f"收到密文：\n{encrypted_data}")
                    # 解密数据
                    decrypted_data = xor_crypt(encrypted_data, key)
                    print(f"解密结果为：\n{decrypted_data}")
                    # 保存解密后的文件
                    save_path = f"decrypted_{filename}"
                    with open(save_path, "wb") as file:
                        file.write(decrypted_data)
                    print(f"[+] 文件已解密保存到: {save_path}")
                    # 发送确认信息给客户端
                    client_socket.send(f"文件接收解密成功，保存为: {save_path}".encode())

                except Exception as e:
                    print(f"[!] 解密失败: {str(e)}")
                    client_socket.send(f"解密失败: {str(e)}".encode())

    except Exception as e:
        print(f"[!] 处理 {addr} 时出错: {str(e)}")
    finally:
        client_socket.close()


def start_server(host, port):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((host, port))
    server.listen(5)
    print(f"[*] 服务器监听 {host}:{port}")

    try:
        while True:
            client_sock, addr = server.accept()
            client_handler = threading.Thread(
                target=handle_client,
                args=(client_sock, addr)
            )
            client_handler.start()
    except KeyboardInterrupt:
        print("\n[*] 服务器关闭")
    finally:
        server.close()



HOST = "192.168.0.103"
PORT = 5555
start_server(HOST, PORT)